home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / +system+ / tools / sound / ahi / developer / devloper.lzx / examples / Low-level / SimplePlay / SimplePlay.c < prev    next >
C/C++ Source or Header  |  1980-02-22  |  11KB  |  396 lines

  1. /* Simple sample player for AHI using the low-level API.
  2.    Hardcoded sample names.
  3.  
  4.    This software is Public Domain. */
  5.  
  6. #include <devices/ahi.h>
  7. #include <exec/exec.h>
  8. #include <proto/ahi.h>
  9. #include <proto/dos.h>
  10. #include <proto/exec.h>
  11.  
  12. #define USE_AHI_V4 TRUE
  13.  
  14. #define CHANNELS   2
  15. #define MAXSAMPLES 16
  16.  
  17. #define INT_FREQ   50
  18.  
  19. char *ID = "$VER: SimplePlay 1.3 (23.4.97)\r\n";
  20.  
  21. APTR samples[MAXSAMPLES] = { 0 };
  22.  
  23. struct {
  24.   BOOL      FadeVolume;
  25.   Fixed     Volume;
  26.   sposition Position;
  27. } channelstate[CHANNELS];
  28.  
  29. struct {
  30.   struct AHIEffDSPMask mask;
  31.   UBYTE                mode[CHANNELS];
  32. } maskeffect = {0};
  33. struct AHIDSPEcho    echoeffect = {0};
  34.  
  35. struct Library      *AHIBase;
  36. struct MsgPort      *AHImp     = NULL;
  37. struct AHIRequest   *AHIio     = NULL;
  38. BYTE                 AHIDevice = -1;
  39. struct AHIAudioCtrl *actrl     = NULL;
  40.  
  41. LONG mixfreq = 0;
  42.  
  43. /* Prototypes */
  44.  
  45. BOOL  OpenAHI(void);
  46. void  CloseAHI(void);
  47. BOOL  AllocAudio(void);
  48. void  FreeAudio(void);
  49. UWORD LoadSample(unsigned char * , ULONG );
  50. void  UnloadSample(UWORD );
  51. int   main(void);
  52.  
  53. /******************************************************************************
  54. ** PlayerFunc *****************************************************************
  55. ******************************************************************************/
  56.  
  57. __asm __interrupt __saveds static void PlayerFunc(
  58.     register __a0 struct Hook *hook,
  59.     register __a2 struct AHIAudioCtrl *actrl,
  60.     register __a1 APTR ignored) {
  61.  
  62.   int i;
  63.   
  64.   for(i = 0; i < CHANNELS; i++) {
  65.  
  66.     if(channelstate[i].FadeVolume) {
  67.  
  68.       channelstate[i].Volume = (channelstate[i].Volume * 90) / 100; // Fade volume
  69.  
  70.       if(channelstate[i].Volume == 0) {
  71.         channelstate[i].FadeVolume = FALSE;
  72.       }
  73.  
  74.       AHI_SetVol(i, channelstate[i].Volume, channelstate[i].Position,
  75.           actrl, AHISF_IMM);
  76.     }
  77.   }
  78.   return;
  79. }
  80.  
  81. struct Hook PlayerHook = {
  82.   0,0,
  83.   (ULONG (* )()) PlayerFunc,
  84.   NULL,
  85.   NULL,
  86. };
  87.  
  88. /******************************************************************************
  89. **** OpenAHI ******************************************************************
  90. ******************************************************************************/
  91.  
  92. /* Open the device for low-level usage */
  93.  
  94. BOOL OpenAHI(void) {
  95.  
  96.   if(AHImp = CreateMsgPort()) {
  97.     if(AHIio = (struct AHIRequest *)CreateIORequest(
  98.         AHImp,sizeof(struct AHIRequest))) {
  99.  
  100. #if USE_AHI_V4
  101.       AHIio->ahir_Version = 4;
  102. #else
  103.       AHIio->ahir_Version = 2;
  104. #endif
  105.  
  106.       if(!(AHIDevice = OpenDevice(AHINAME, AHI_NO_UNIT,
  107.           (struct IORequest *) AHIio,NULL))) {
  108.         AHIBase = (struct Library *) AHIio->ahir_Std.io_Device;
  109.         return TRUE;
  110.       }
  111.     }
  112.   }
  113.   FreeAudio();
  114.   return FALSE;
  115. }
  116.  
  117.  
  118. /******************************************************************************
  119. **** CloseAHI *****************************************************************
  120. ******************************************************************************/
  121.  
  122. /* Close the device */
  123.  
  124. void CloseAHI(void) {
  125.  
  126.   if(! AHIDevice)
  127.     CloseDevice((struct IORequest *)AHIio);
  128.   AHIDevice=-1;
  129.   DeleteIORequest((struct IORequest *)AHIio);
  130.   AHIio=NULL;
  131.   DeleteMsgPort(AHImp);
  132.   AHImp=NULL;
  133. }
  134.  
  135.  
  136. /******************************************************************************
  137. **** AllocAudio ***************************************************************
  138. ******************************************************************************/
  139.  
  140. /* Ask user for an audio mode and allocate it */
  141.  
  142. BOOL AllocAudio(void) {
  143.   struct AHIAudioModeRequester *req;
  144.   BOOL   rc = FALSE;
  145.  
  146.   req = AHI_AllocAudioRequest(
  147.       AHIR_PubScreenName, NULL,
  148.       AHIR_TitleText,     "Select a mode and rate",
  149.       AHIR_DoMixFreq,     TRUE,
  150.       TAG_DONE);
  151.  
  152.   if(req) {
  153.     if(AHI_AudioRequest(req, TAG_DONE)) {
  154.       actrl = AHI_AllocAudio(
  155.           AHIA_AudioID,         req->ahiam_AudioID,
  156.           AHIA_MixFreq,         req->ahiam_MixFreq,
  157.           AHIA_Channels,        CHANNELS,
  158.           AHIA_Sounds,          MAXSAMPLES,
  159.           AHIA_PlayerFunc,      &PlayerHook,
  160.           AHIA_PlayerFreq,      INT_FREQ<<16,
  161.           AHIA_MinPlayerFreq,   INT_FREQ<<16,
  162.           AHIA_MaxPlayerFreq,   INT_FREQ<<16,
  163.           TAG_DONE);
  164.       if(actrl) {
  165.         // Get real mixing frequency
  166.         AHI_ControlAudio(actrl, AHIC_MixFreq_Query, &mixfreq, TAG_DONE);
  167.         rc = TRUE;
  168.       }
  169.     }
  170.     AHI_FreeAudioRequest(req);
  171.   }
  172.   return rc;
  173. }
  174.  
  175.  
  176. /******************************************************************************
  177. **** FreeAudio ****************************************************************
  178. ******************************************************************************/
  179.  
  180. /* Release the audio hardware */
  181.  
  182. void FreeAudio() {
  183.  
  184.   AHI_FreeAudio(actrl);
  185.   actrl = NULL;
  186. }
  187.  
  188. /******************************************************************************
  189. **** LoadSample ***************************************************************
  190. ******************************************************************************/
  191.  
  192. /* Load a (raw) 8 or 16 bit sample from disk. The sample ID is returned
  193.    (or AHI_NOSOUND on error). */
  194.  
  195. UWORD LoadSample(char *filename, ULONG type) {
  196.   struct AHISampleInfo sample;
  197.   APTR *samplearray = samples;
  198.   UWORD id = 0, rc = AHI_NOSOUND;
  199.   BPTR file;
  200.  
  201.   // Find a free sample slot
  202.  
  203.   while(*samplearray) {
  204.     id++;
  205.     samplearray++;
  206.     if(id >= MAXSAMPLES) {
  207.       return AHI_NOSOUND;
  208.     }
  209.   }
  210.  
  211.   file = Open(filename, MODE_OLDFILE);
  212.   
  213.   if(file) {
  214.     int length;
  215.  
  216.     Seek(file, 0, OFFSET_END);
  217.     length = Seek(file, 0, OFFSET_BEGINNING);
  218.     *samplearray = AllocVec(length, MEMF_PUBLIC);
  219.     if(*samplearray) {
  220.       Read(file, *samplearray, length);
  221.  
  222.       sample.ahisi_Type = type;
  223.       sample.ahisi_Address = *samplearray;
  224. #if USE_AHI_V4
  225.       sample.ahisi_Length = length / AHI_SampleFrameSize(type);
  226. #else
  227.       sample.ahisi_Length = length / (type == AHIST_M16S ? 2 : 1);
  228. #endif
  229.       if(! AHI_LoadSound(id, AHIST_SAMPLE, &sample, actrl)) {
  230.         rc = id;
  231.       }
  232.     }
  233.     Close(file);
  234.   }
  235.   return rc;
  236. }
  237.  
  238.  
  239. /******************************************************************************
  240. **** UnloadSample *************************************************************
  241. ******************************************************************************/
  242.  
  243. void UnloadSample(UWORD id) {
  244.  
  245.   AHI_UnloadSound(id, actrl);
  246.   FreeVec(samples[id]);
  247.   samples[id] = NULL;
  248. }
  249.  
  250. /******************************************************************************
  251. **** main *********************************************************************
  252. ******************************************************************************/
  253.  
  254. int main() {
  255.   UWORD sample, ahem, louise;
  256.   int i;
  257.  
  258.   for(i = 0; i < CHANNELS; i++) {
  259.     channelstate[i].FadeVolume = FALSE;
  260.   }
  261.  
  262.   if(OpenAHI()) {
  263.     if(AllocAudio()) {
  264.       ahem   = LoadSample("Projekt:ahi/samples/ASS-14.sb", AHIST_M8S);
  265.       louise = LoadSample("Projekt:ahi/samples/LouiseR.sw", AHIST_M16S);
  266.       if((ahem != AHI_NOSOUND) && (louise != AHI_NOSOUND)) {
  267.  
  268.         // Start feeding samples to sound hardware
  269.         if(!(AHI_ControlAudio(actrl,
  270.             AHIC_Play, TRUE,
  271.             TAG_DONE)))
  272.         {
  273.  
  274. #if USE_AHI_V4
  275.           Printf("Playing two samples, one with echo and one without.\n");
  276.  
  277.           // Turn on echo on channel 1
  278.           // No error checking here, but you should do that.
  279.           maskeffect.mask.ahie_Effect = AHIET_DSPMASK;
  280.           maskeffect.mask.ahiedm_Channels = CHANNELS;
  281.           maskeffect.mode[0] = AHIEDM_DRY;
  282.           maskeffect.mode[1] = AHIEDM_WET;
  283.           AHI_SetEffect( &maskeffect, actrl );
  284.           
  285.           echoeffect.ahie_Effect     = AHIET_DSPECHO;
  286.           echoeffect.ahiede_Delay    = mixfreq / 4; // 250 ms
  287.           echoeffect.ahiede_Feedback = 0x8000;      // 50 %
  288.           echoeffect.ahiede_Mix      = 0x10000;     // 100% and...
  289.           echoeffect.ahiede_Cross    = 0;           // ...0% gives faster echo code.
  290.           AHI_SetEffect( &echoeffect, actrl );
  291.  
  292.           AHI_Play(actrl,
  293.             // A forever-looping sample on channel 0
  294.             AHIP_BeginChannel,  0,
  295.             AHIP_Freq,          17640,
  296.             AHIP_Vol,           0x10000,
  297.             AHIP_Pan,           0xc000,
  298.             AHIP_Sound,         louise,
  299.             AHIP_EndChannel,    NULL,
  300.  
  301.             // A oneshot sample on channel 1
  302.             AHIP_BeginChannel,  1,
  303.             AHIP_Freq,          22254,
  304.             AHIP_Vol,           0x10000,
  305.             AHIP_Pan,           0x4000,
  306.             AHIP_Sound,         ahem,
  307.             AHIP_LoopSound,     AHI_NOSOUND,
  308.             AHIP_EndChannel,    NULL,
  309.  
  310.             TAG_DONE);
  311. #else
  312.           Printf("Playing two samples.\n");
  313.  
  314.           // A forever-looping sample on channel 0
  315.           AHI_SetFreq(0, 17640, actrl, AHISF_IMM);
  316.           AHI_SetVol(0, 0x10000, 0xc000, actrl, AHISF_IMM);
  317.           AHI_SetSound(0, louise, 0, 0, actrl, AHISF_IMM);
  318.  
  319.           // A oneshot sample on channel 1
  320.           AHI_SetFreq(1, 22254, actrl, AHISF_IMM);
  321.           AHI_SetVol(1, 0x10000, 0x4000, actrl, AHISF_IMM);
  322.           AHI_SetSound(1, ahem, 0, 0, actrl, AHISF_IMM);
  323.           AHI_SetSound(1, AHI_NOSOUND, 0, 0, actrl, 0);
  324. #endif
  325.           channelstate[0].Volume   = 0x10000;
  326.           channelstate[0].Position = 0xc000;
  327.           channelstate[1].Volume   = 0x10000;
  328.           channelstate[1].Position = 0x4000;
  329.  
  330.           // Wait 5 seconds
  331.           
  332.           Delay(5 * TICKS_PER_SECOND);
  333.  
  334. #if USE_AHI_V4
  335.           Printf("Turning on echo on channel 0.\n");
  336.  
  337.           // Turn on echo on channel 0, turn off channel 1
  338.           // No error checking here, but you should do that.
  339.           maskeffect.mode[0] = AHIEDM_WET;
  340.           maskeffect.mode[1] = AHIEDM_DRY;
  341.           AHI_SetEffect( &maskeffect, actrl );
  342. #endif
  343.  
  344.           // Wait 5 seconds
  345.           
  346.           Delay(5 * TICKS_PER_SECOND);
  347.  
  348.           Printf("Fading away the sound on channel 0... ");
  349.           Flush(Output());
  350.  
  351.           // Fade away channel 0
  352.           
  353.           channelstate[0].FadeVolume = TRUE;
  354.  
  355.           while(channelstate[0].FadeVolume) {
  356.             Delay(1);
  357.           }
  358.  
  359.           Printf("Done!\n");
  360.  
  361.           // Wait a sec...
  362.  
  363.           Delay(TICKS_PER_SECOND);
  364.  
  365.           // Stop sounds
  366.           AHI_ControlAudio(actrl,
  367.               AHIC_Play, FALSE,
  368.               TAG_DONE);
  369.  
  370.  
  371. #if USE_AHI_V4
  372.           // Cancel effects
  373.  
  374.           maskeffect.mask.ahie_Effect = AHIET_DSPMASK | AHIET_CANCEL;
  375.           AHI_SetEffect( &maskeffect, actrl );
  376.           
  377.           echoeffect.ahie_Effect     = AHIET_DSPECHO | AHIET_CANCEL;
  378.           AHI_SetEffect( &echoeffect, actrl );
  379. #endif
  380.  
  381.         }
  382.       }
  383.  
  384.       // Ask AHI to unload all loaded samples and free the memory for them 
  385.       for(sample = 0; sample < MAXSAMPLES; sample++) {
  386.         UnloadSample(sample);
  387.       }
  388.  
  389.     }
  390.     FreeAudio();
  391.   }
  392.   CloseAHI();
  393.  
  394.   return 0;
  395. }
  396.